﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web.Http;
using FimetContoDeposito.BLL.Facades;
using FimetContoDeposito.BLL.Objects;
using FimetContoDeposito.BLL.ResultSets;
using FimetContoDeposito.DAL;
using GrayParrot.Core;
using GrayParrot.Core.Json;
using GrayParrot.Web.Controls;
using GrayParrot.Web.Formly;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace FimetContoDeposito.Controllers
{
	public class FornitoriController : GridCrudController<FCD_Fornitori, DTParameters>
	{
        #region Loading Fields...
        [HttpGet]
        public string LoadFields()
        {
            string retValue = null;

            //var m_fields = FormlyHelper.ToFormly<AnagraficaFamiglieMetadata>(typeof(AnagraficaFamiglieMetadata));

            var m_fields = new FormlyFactory()
                   .AddInput("descrizione", "Descrizione", "", "inserisci la descrizione", false, true, 0, 0)
                   .AddInput("note", "Note", "", "inserisci le note", false, false, 0, 0)
                   .Create();

            JsonSerializerSettings settings = new JsonSerializerSettings();
            settings.ContractResolver = new NullToEmptyListResolver();
            settings.Converters = new List<JsonConverter> { new Newtonsoft.Json.Converters.StringEnumConverter { CamelCaseText = false } };
            settings.Formatting = Formatting.Indented;
            settings.NullValueHandling = NullValueHandling.Ignore;

            retValue = JsonConvert.SerializeObject(m_fields, settings);

            return retValue;
        }

        [HttpGet]
        public string[] LoadFields(Guid id)
        {
            string[] retValue = new string[2] { string.Empty, string.Empty };

            FCD_Fornitori obj = null;
            using (FornitoriFacade m_dc = FornitoriFacade.Create())
            {
                ReturnValue<FCD_Fornitori> m_objs = m_dc.Get(id);
                if (m_objs.HasValue)
                {
                    obj = m_objs.Value;
                }
            }

            if (obj != null)
            {
                //var m_fields = FormlyHelper.ToFormly<AnagraficaFamiglieMetadata>(typeof(AnagraficaFamiglieMetadata));
                var m_fields = new FormlyFactory()
                                   .AddInput("Descrizione", "Descrizione", "", "inserisci la descrizione", false, true, 0, 0)
                                   .AddInput("Note", "Note", "", "inserisci le note", false, false, 0, 0)
                                   .Create();

                JsonSerializerSettings settings = new JsonSerializerSettings();
                settings.ContractResolver = new NullToEmptyListResolver();
                settings.Converters = new List<JsonConverter> { 
                    new Newtonsoft.Json.Converters.StringEnumConverter { CamelCaseText = false }
                };

                settings.Formatting = Formatting.Indented;
                settings.NullValueHandling = NullValueHandling.Ignore;

                retValue[0] = JsonConvert.SerializeObject(m_fields, settings);

                retValue[1] = JsonConvert.SerializeObject(obj);
            }
            else
            {
            }

            //
            return retValue;
        }

        [HttpGet]
        public string LoadAssociazioniFields()
        {
            string retValue = null;

            //var m_fields = FormlyHelper.ToFormly<AnagraficaFamiglieMetadata>(typeof(AnagraficaFamiglieMetadata));

            var m_fields = new FormlyFactory()
                   .AddSelect("Fornitori", "Fornitori", "", "seleziona il fornitore", false, true, null, "/api/Common/LoadFornitori")
                   .AddEvent(EventTypes.OnChange, "FornitoreChangeCallback")
                   .Create();

            retValue = FormlyHelper.Serialize(m_fields);

            return retValue;
        }
        #endregion

        public override System.Net.Http.HttpResponseMessage Load(DTParameters data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            using (FornitoriFacade m_dc = FornitoriFacade.Create())
            {
                ReturnValue<IQueryable<FCD_Fornitori>> m_objs = m_dc.GetAll();

                DTResult<FCD_Fornitori> result = DTResult<FCD_Fornitori>.Empty("Nessun elemento trovato");
                if (m_objs.HasValue)
                {
                    FornitoriResultSet m_rs = new FornitoriResultSet(data, m_objs.Value);
                    result = m_rs.GetResult();
                }
                else
                {
                    if (m_objs.HasError)
                    {
                        result.Message.MessageType = MessageTypes.Error;
                        result.Message.Message = m_objs.Error.Message;
                    }
                }

                retValue = Request.CreateResponse(HttpStatusCode.OK, result);
            }

            return retValue;
        }

        public override System.Net.Http.HttpResponseMessage Add(FCD_Fornitori data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            using (FornitoriFacade m_dc = FornitoriFacade.Create())
            {
                ReturnValue<bool> result = m_dc.Add(data);

                if (result.HasValue)
                {
                    retValue = Request.CreateResponse(HttpStatusCode.OK, "Inserimento Fornitore eseguito !");
                }
                else
                {
                    retValue = Request.CreateResponse(HttpStatusCode.OK, "Errore nell'inserimento del Fornitore");
                }
            }

            return retValue;
        }

        public override System.Net.Http.HttpResponseMessage Edit(FCD_Fornitori data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            using (FornitoriFacade m_dc = FornitoriFacade.Create())
            {
                ReturnValue<bool> result = m_dc.Edit(data);

                if (result.HasValue)
                {
                    retValue = Request.CreateResponse(HttpStatusCode.OK, "Modifica Fornitore eseguito !");
                }
                else
                {
                    retValue = Request.CreateResponse(HttpStatusCode.OK, "Errore nella modifica del Fornitore");
                }
            }

            return retValue;
        }

        public override HttpResponseMessage Delete(int id)
        {
            throw new NotImplementedException();
        }

        [HttpPost]
        public override System.Net.Http.HttpResponseMessage Delete(JObject data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            dynamic json = data;
            Guid m_id = Guid.Parse(json.id.ToString());

            using (FornitoriFacade m_dc = FornitoriFacade.Create())
            {
                ReturnValue<FCD_Fornitori> m_obj = m_dc.Get(m_id);

                if (m_obj.HasValue)
                {
                    ReturnValue<bool> result = m_dc.Delete(m_obj.Value);

                    if (result.HasValue)
                    {
                        retValue = Request.CreateResponse(HttpStatusCode.OK, "Cancellazione Fornitore effettuata !");
                    }
                    else
                    {
                        retValue = Request.CreateResponse(HttpStatusCode.OK, "Cancellazione annullata - Fornitore con codici fornitori o utilizzato in movimenti di magazzino.");
                    }

                }
                else
                {
                    retValue = Request.CreateResponse(HttpStatusCode.OK, "Errore nella selezione del Fornitore");
                }
            }

            return retValue;
        }

        [HttpGet]
        public List<NameValue<string, Guid>> LoadFornitori()
        {
            List<NameValue<string, Guid>> retValue = null;

            using (FornitoriFacade m_cf = FornitoriFacade.Create())
            {
                ReturnValue<IEnumerable<NameValue<string, Guid>>> result = m_cf.GetAllNameValue();
                if (result.HasValue)
                {
                    retValue = result.Value.ToList();
                }
            }

            return retValue;
        }

        [HttpPost]
        public ReturnValue<FCD_Fornitori> GetFornitore(JObject data)
        {
            ReturnValue<FCD_Fornitori> retValue = new ReturnValue<FCD_Fornitori>(null);

            dynamic json = data;
            Guid m_idFornitore = Guid.Parse(FormlyExtensions.SanitizeDropdownItem(json.idFornitore));
            using (FornitoriFacade m_cf = FornitoriFacade.Create())
            {
                ReturnValue<FCD_Fornitori> result = m_cf.Get(m_idFornitore);
                if (result.HasValue)
                {
                    retValue.Value = result.Value;
                    retValue.HasValue = true;
                }
            }

            return retValue;
        }

        /// <summary>
        /// Carica i clienti di un fornitore...
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        [HttpPost]
        public System.Net.Http.HttpResponseMessage LoadAssociatedCustomers(JObject data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            dynamic json = data;
            Guid m_idFornitore = Guid.Parse(FormlyExtensions.SanitizeDropdownItem(json.Fornitore));

            CommonController m_cc = new CommonController();

            AssociazioneClientiFornitori m_assCustomers = new AssociazioneClientiFornitori();
            m_assCustomers.Clienti = m_cc.LoadCustomers();

            List<NameValue<string, Guid>> m_asC = null;
            using (FornitoriFacade m_ff = FornitoriFacade.Create())
            {
                ReturnValue<FCD_Fornitori> m_resF = m_ff.Get(m_idFornitore, "FCD_Customers");

                if (m_resF.HasValue)
                {
                    if (m_resF.Value != null && m_resF.Value.FCD_Customers.Count() > 0)
                    {
                        m_asC = m_resF.Value.FCD_Customers.Select(x => new NameValue<string, Guid>() { name = x.RagioneSociale, value = x.Id }).ToList();
                        m_assCustomers.Associati = m_asC;
                    }
                }
            }

            retValue = Request.CreateResponse(HttpStatusCode.OK, m_assCustomers);
            return retValue;
        }

        /// <summary>
        /// Salva l'associazione tra fornitori e clienti...
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        [HttpPost]
        public System.Net.Http.HttpResponseMessage SalvaAssociazioneClienti(JObject data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            dynamic json = data;
            Guid m_idFornitore = Guid.Parse(FormlyExtensions.SanitizeDropdownItem(json.Fornitore));
            string[] m_clienti = json.Clienti.ToObject<string[]>();

            List<Guid> m_gc = null;
            ReturnValue<bool> resultC = new ReturnValue<bool>(false);
            using (FornitoriFacade m_dc = FornitoriFacade.Create())
            {
                if (m_clienti != null)
                {
                    m_gc = m_clienti.Select(Guid.Parse).ToList();
                }

                resultC = m_dc.CancellaAssociazioneClienti(m_idFornitore);
            }

            if (resultC.HasValue && resultC.Value)
            {
                using (FornitoriFacade m_dc = FornitoriFacade.Create())
                {
                    ReturnValue<bool> resultA = m_dc.SaveAssociazioneClienti(m_idFornitore, m_gc);

                    if (resultA.HasValue && resultA.Value)
                    {
                        retValue = Request.CreateResponse(HttpStatusCode.OK, "Salvataggio associazione Clienti - Fornitore effettuata !");
                    }
                    else
                    {
                        if (!resultA.Value)
                        {
                            retValue = Request.CreateResponse(HttpStatusCode.OK, resultA.Message);
                        }
                        else
                        {
                            retValue = Request.CreateResponse(HttpStatusCode.OK, "Errore nel salvataggio associazione clienti - Fornitore");
                        }
                    }
                }
            }

            return retValue;
        }

        /// <summary>
        /// Cancella l' associazione tra fornitori e clienti...
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        [HttpPost]
        public System.Net.Http.HttpResponseMessage CancellaAssociazioneClienti(JObject data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            dynamic json = data;
            Guid m_idFornitore = Guid.Parse(FormlyExtensions.SanitizeDropdownItem(json.Fornitore));

            using (FornitoriFacade m_dc = FornitoriFacade.Create())
            {
                ReturnValue<bool> result = m_dc.CancellaAssociazioneClienti(m_idFornitore);

                if (result.HasValue)
                {
                    retValue = Request.CreateResponse(HttpStatusCode.OK, "Cancellazione associazione Clienti - Fornitore effettuata !");
                }
                else
                {
                    retValue = Request.CreateResponse(HttpStatusCode.OK, "Errore nella cancellazione associazione Clienti - Fornitore");
                }
            }

            return retValue;
        }

        /// <summary>
        /// Carica i fornitori di un cliente...
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        [HttpPost]
        public List<NameValue<string, Guid>> LoadFornitoriByCustomer(JObject data)
        {
            List<NameValue<string, Guid>> retValue = null;

            dynamic json = data;
            Guid m_idCustomer = Guid.Parse(json.parameters[0].ToString());

            using (FornitoriFacade m_dc = FornitoriFacade.Create())
            {
                ReturnValue<List<NameValue<string, Guid>>> result = m_dc.LoadFornitoriByCustomer(m_idCustomer);

                if (result.HasValue)
                {
                    retValue = result.Value;
                }
            }

            return retValue;
        }

        /// <summary>
        /// Carica i fornitori di un cliente. 
        /// Se il cliente non ha fornitori associati, allora carica tutti i fornitori...
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        [HttpPost]
        public List<NameValue<string, Guid>> LoadFornitoriByCustomerOrAll(JObject data)
        {
            List<NameValue<string, Guid>> retValue = null;

            dynamic json = data;

            Guid m_idCustomer = Guid.Empty;

            if (json.parameters != null)
            {
                m_idCustomer = Guid.Parse(json.parameters.ToString());
            }

            using (FornitoriFacade m_dc = FornitoriFacade.Create())
            {
                ReturnValue<List<NameValue<string, Guid>>> result = null;

                if (m_idCustomer != Guid.Empty)
                {
                    result = m_dc.LoadFornitoriByCustomer(m_idCustomer);

                    if (result.HasValue)
                    {
                        retValue = result.Value;
                    }
                    //else
                    //{
                    //    ReturnValue<IEnumerable<NameValue<string, Guid>>> ret = m_dc.GetAllNameValue();
                    //    if (ret.HasValue && ret.Value != null)
                    //    {
                    //        retValue = ret.Value.ToList();
                    //    }
                    //}
                }

                if ((result == null) || (!result.HasValue))    
                {
                    result = m_dc.LoadFornitoriNotAssociatedToCustomers(); // m_dc.GetAllNameValue();
                    if (result.HasValue && result.Value != null)
                    {
                        retValue = result.Value;
                    }
                }
            }


            return retValue;
        }
	}
}
